#!/usr/bin/env python
# Copyright (C) 2008 Marcin Cieslik <marcin.cieslik@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
import unittest
import numpy
import zenpdb
#NUMPY

class test_crystal(unittest.TestCase):
    def setUp(self):
        pass
    def _run_contacts(self,file_name, sym_args, cry_args, con_args):
        from zenpdb.PDBParser import PDBParser
        from zenpdb.Crystal import Crystal
        from zenpdb.Contacts import ACTAtomContacts
        from time import time
        parser = PDBParser()
        parser.set_file(file_name)
        structure = parser.get_structure()
        model = structure[(0,)]
        crystal = Crystal(structure)
        crystal.set_symmetry(**sym_args)
        crystal.set_crystal(**cry_args)
        crystal.center_asu()
        a = time()
        act = ACTAtomContacts(file_name, model)
        b = time()
        print b - a
        a = time()
        cry = crystal.get_contacts(**con_args)
        b = time()
        print b - a
        return (act, cry)
    def _test_contacts(self,res_act, res_cry):
        actlefts = res_act.keys()
        crylefts = res_cry.keys()
        alllefts = []
        alllefts.extend(actlefts)
        alllefts.extend(crylefts)
        alllefts = sorted(list(set(alllefts)))
        errors = []
        def cmp_rights(res_act_rights, res_cry_rights):
            act_rights = res_act_rights.keys()
            cry_rights = res_cry_rights.keys()
            allrights = []
            allrights.extend(act_rights)
            allrights.extend(cry_rights)
            allrights = sorted(list(set(allrights)))
            for right in allrights:
                flag = "WRONG"
                act_right_value = res_act_rights.get(right)
                cry_right_value = res_cry_rights.get(right)
                try:
                    if abs(act_right_value[0] - cry_right_value[0]) < 0.00501:
                        flag = 'right'
                except:
                    pass
                if flag == 'WRONG':
                    #print left,
                    #print "\t%s   " % (right,),
                    #print "\t%37s\t%27s" % (act_right_value, cry_right_value)
                    errors.append((left, right, act_right_value, cry_right_value))
        for left in alllefts:
            act_rights = (res_act.get(left) or {})
            cry_rights = (res_cry.get(left) or {})
            cmp_rights(act_rights, cry_rights)
        return errors

        pass
    def _run_asa():
        pass
    def _test_asa():
        pass
    def test_import(self):
        from zenpdb import Crystal
    def test_contacts(self):
        #monomeric_p1
        res_act, res_cry = self._run_contacts('files/cruncherpdb/c1AKY.pdb', {},{},{})
        errors = self._test_contacts(res_act, res_cry)
        assert len(errors) == 1, len(errors)
        assert errors[0][2] is None

        #dimeric_p1
        res_act, res_cry = self._run_contacts('files/cruncherpdb/c1CSE.pdb', {},{},{'mode':'diff_chain'})
        errors = self._test_contacts(res_act, res_cry)
        assert len(errors) == 1
        assert errors[0][2] is None

        #monomeric p3
        res_act, res_cry = self._run_contacts('files/cruncherpdb/c1W5D.pdb', {},{},{})
        errors = self._test_contacts(res_act, res_cry)
        assert len(errors) == 1
        assert errors[0][2] is None

        #dimeric p3
        res_act, res_cry = self._run_contacts('files/cruncherpdb/c1MBY.pdb', {},{},{'mode':'diff_chain'})
        errors = self._test_contacts(res_act, res_cry)
        assert len(errors) == 1
        assert errors[0][2] is None

        #multimeric c2
        res_act, res_cry = self._run_contacts('files/cruncherpdb/c2JHV.pdb', {},{},{'mode':'diff_chain'})
        errors = self._test_contacts(res_act, res_cry)
        assert len(errors) == 1
        assert errors[0][2] is None

        #multimeric p4
        res_act, res_cry = self._run_contacts('files/cruncherpdb/c1B09.pdb', {},{},{'mode':'diff_chain'})
        errors = self._test_contacts(res_act, res_cry)
        assert len(errors) == 1
        assert errors[0][2] is None

    def tearDown(self):
        pass
    def test_asa(self):
        pass

suite = unittest.makeSuite(test_crystal,'test')

if __name__ == "__main__":
    runner = unittest.TextTestRunner()
    runner.run(suite)
